#import "FDApplication.h"

@implementation FDApplication
- (id)init
{
	if(self = [super init])
	{
		// Application Initialized
	}
	return self;
}

#pragma mark Application Launch and Suspend
- (void)applicationDidFinishLaunching:(id)unused
{
	NSLog(@"%s", _cmd);
	
	_contentRect = [UIHardware fullScreenApplicationContentRect];
	_contentRect.origin.x = 0.0f;
	_contentRect.origin.y = 0.0f;
	
	defaults = [[FDDefaultsController alloc] init];
	mainWindow = [[UIWindow alloc] initWithContentRect:[UIHardware fullScreenApplicationContentRect]];
	mainView = [[UIView alloc] initWithFrame:_contentRect];
	
	UIImageView	*background = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, _contentRect.size.width, _contentRect.size.height)];
	[background setImage:[UIImage applicationImageNamed:@"greenfelt.png"]];	
	[mainView addSubview:background];
	[background release];
	
	navBar = [[UINavigationBar alloc] init];
	[navBar setFrame:CGRectMake(_contentRect.origin.x, _contentRect.origin.y, _contentRect.size.width, 45.0f)];
	[navBar setBarStyle:1];
	[navBar setImage:[UIImage applicationImageNamed:@"navbar.png"]];
	
	[navBar setDelegate:self];
	[navBar enableAnimation];
	
	navBarTitle = [[UINavigationItem alloc] init];
	[navBar pushNavigationItem:navBarTitle];
	
	[mainView addSubview:navBar];
	
	[mainWindow setContentView:mainView];
	
	[mainWindow orderFront:self];
	[mainWindow makeKey:self];
	[mainWindow _setHidden:NO];
	
	// Get a MenuView and a GameView and place them off screen
	gameMenuView = [[FDGameMenuView alloc] initWithFrame:CGRectMake(_contentRect.origin.x - _contentRect.size.width,
		_contentRect.origin.y + 45.0f,
		_contentRect.size.width,
		_contentRect.size.height - 45.0f)];
	[gameMenuView setDelegate:self];
	[mainView addSubview:gameMenuView];
		
	gameView = [[FDGameView alloc] initWithFrame:CGRectMake(_contentRect.origin.x + _contentRect.size.width,
		_contentRect.origin.y + 45.0f,
		_contentRect.size.width,
		_contentRect.size.height - 45.0f)];
	[gameView setDelegate:self];
	[mainView addSubview:gameView];
	
	[self setCurrentState:[[NSUserDefaults standardUserDefaults] integerForKey:@"SavedState"]];
	[self finishUserInterfaceForState:[self currentState]];
}

- (void)applicationWillSuspend
{
	NSLog(@"%s With Current State: %i", _cmd, [self currentState]);
	[defaults setSavedState:[self currentState]];
	if ([self currentState] == INGAME) [self saveGamePosition];
}

- (void)saveGamePosition
{
	[defaults setRollCount:[gameView rollCount]];
	[defaults setLastRoll:[gameView lastRoll]];
	[defaults setTurnCount:[gameView turnCount]];
	[defaults setDiceTotal:[gameView diceTotal]];
	[defaults setWildcard:[gameView wildcard]];
	[defaults setYahtzeeCount:[gameView yahtzeeCount]];
	[defaults setSelectedRow:[gameView selectedRow]];
	[defaults setLastSelectedRow:[gameView lastScore]];
	
	[defaults setDiceValues:[gameView pDiceValues]];
	[defaults setScores:[gameView scoreCardScores]];
	[defaults setScoresSet:[gameView scoreCardSetScores]];
	[defaults synchronize];
}

#pragma mark Persistence Methods


#pragma mark Handle Current State

// This will finish loading the views based on the saved game state
- (void)finishUserInterfaceForState:(int)state
{
	NSLog(@"%s Current State: %i", _cmd, state);
	switch (state) {
		case NEWGAME:
		[self startNewGame];
		break;
		case INGAME:
		[self continueLastGameWithOver:NO];
		break;
		case GAMEOVER:
		[self continueLastGameWithOver:YES];
		break;
		default:
		[self showGameMenu];
	}
}

#pragma mark Show and Hide Views

- (void)showGameMenu
{
	NSLog(@"%s", _cmd);
	if ([self currentState] == INGAME || [self currentState] == NEWGAME || [self currentState] == GAMEOVER) [gameView hide];
	[self changeStateTo:MENU];
	// This timer gives the score card a chance to start hiding before we slide things out
	NSTimer		*animDelay = [NSTimer scheduledTimerWithTimeInterval:0.2
										  	  target:self
											selector:@selector(showGameMenuAfterDelay:)
											userInfo:nil
										 	 repeats:NO];
}

- (void)showGameMenuAfterDelay:(NSTimer *)aTimer
{
	[aTimer invalidate];
	[gameMenuView show];
}

- (void)showGameView
{
	NSLog(@"%s", _cmd);
	if ([self currentState] == MENU) [gameMenuView hide];
	[gameView show];
	[self changeStateTo:INGAME];
}

- (void)waitForNewGameSetup:(NSTimer *)aTimer
{
	[aTimer invalidate];
	[self showGameView];
	[self changeStateTo:NEWGAME];
}

- (void)startNewGame // Also used as a delegate for GameMenu Button
{
	NSLog(@"%s", _cmd);
	[gameView newGame];
	
	// This timer creates a small dealy so the new game stuff finishes before we the views in
	NSTimer		*newGameDelay = [NSTimer scheduledTimerWithTimeInterval:0.2
										  	  target:self
											selector:@selector(waitForNewGameSetup:)
											userInfo:nil
										 	 repeats:NO];
}

- (void)continueLastGameWithOver:(BOOL)over
{
	NSLog(@"%s", _cmd);

	[gameView setRollCount:[defaults rollCount]];
	[gameView setLastRoll:[defaults lastRoll]];
	[gameView setTurnCount:[defaults turnCount]];
	[gameView setDiceTotal:[defaults diceTotal]];
	[gameView setWildcard:[defaults wildcard]];
	[gameView setYahtzeeCount:[defaults yahtzeeCount]];
	[gameView setSelectedRow:[defaults selectedRow]];
	[gameView setLastScore:[defaults lastSelectedRow]];

	[gameView loadSavedGame];
		
	[self updateRollButtonWithLast:NO];
	[self showGameView];
}

#pragma mark Notification and Delegate Responders

- (void)scoreCardSelectionChanged:(NSNotification *)notification
{
	NSLog(@"%s", _cmd);
}

- (void)rolledYahtzee:(NSNotification *)notification
{
	NSLog(@"%s", _cmd);
}

- (void)updateRollButtonWithLast:(BOOL)withLast {
	// NSLog(@"%s Current roll value: %i", _cmd, [gameView rollCount]+1);
	// NSLog(@"%s Last roll value: %i", _cmd, [gameView lastRoll]+1);
	if ([gameView rollCount] < 3 ) {
		if (withLast) {
			[self setNavBarLeftButton:@"Menu" withStyle:2 rightButton:[NSString stringWithFormat:@"Roll %i of 3",[gameView lastRoll]+1] withStyle:1];
		} else {
			[self setNavBarLeftButton:@"Menu" withStyle:2 rightButton:[NSString stringWithFormat:@"Roll %i of 3",[gameView rollCount]+1] withStyle:1];
		}
	} else {
		// NSLog(@"%s Count is >= 3", _cmd);
		[self setNavBarLeftButton:@"Menu" withStyle:2 rightButton:nil withStyle:0];
	}
}

- (void)changeStateTo:(int)state
{
	NSLog(@"%s to: %i", _cmd,state);
	
	if ([self previousState] != INGAME) [self setPreviousState:currentState]; // This prevents not being able to get back to current game
	[self setCurrentState:state];
	
	switch (state) {
		case HIGHSCORES:
		[self setNavBarLeftButton:@"Menu" withStyle:2 rightButton:@"Clear" withStyle:1];
		break;
		case MENU:
		[navBarTitle setTitle:@""];
		if ([self previousState] == INGAME) {
			[self setNavBarLeftButton:@"Keep Playing" withStyle:2 rightButton:@"High Scores" withStyle:0];
		} else {
			[self setNavBarLeftButton:nil withStyle:2 rightButton:@"High Scores" withStyle:0];
		}
		break;
		case GAMEOVER:
		[self setNavBarLeftButton:@"New Game" withStyle:2 rightButton:nil withStyle:0];
		break;
		case INGAME:
		[navBarTitle setTitle:[defaults playerOneName]];
		[self updateRollButtonWithLast:NO];
		//[self setNavBarLeftButton:@"Menu" withStyle:2 rightButton:[NSString stringWithFormat:@"Roll %i of 3",[gameView lastRoll]+1] withStyle:1];
		break;
		case NEWGAME:
		[navBarTitle setTitle:[defaults playerOneName]];
		//[self setNavBarLeftButton:@"Menu" withStyle:2 rightButton:[NSString stringWithFormat:@"Roll %i of 3",[gameView lastRoll]+1] withStyle:1];
		break;
		default:
		[self setNavBarLeftButton:@"Menu" withStyle:2 rightButton:nil withStyle:0];
	}
}

#pragma mark Button delegates

- (void)navigationBar:(UINavigationBar*)bar buttonClicked:(int)button
{
	if (button == 1) {
		NSLog(@"%s Clicked Left Button", _cmd);
		switch ([self currentState]) {
			case HIGHSCORES:
			[gameMenuView hideHighScoresBanner];
			break;
			case MENU:
			[self showGameView];
			[self setCurrentState:INGAME];
			break;
			case INGAME:
			[self showGameMenu];
			break;
			case NEWGAME:
			[self showGameMenu];
			break;
			case GAMEOVER:
			[self showGameMenu];
			break;
		}
		
	} else if (button == 0) {
		NSLog(@"%s Clicked Right Button", _cmd);
		switch ([self currentState]) {
			case HIGHSCORES:
			[self sendAlertWithContext:@"clearhighscores"];
			break;
			case MENU:
			[gameMenuView showHighScoresBanner];
			break;
			case INGAME:
			// Roll
			[gameView rollDice];
			break;
			case NEWGAME:
			// Roll
			[gameView rollDice];
			break;
			case GAMEOVER:
			// nil
			break;
		}
	}
}

#pragma mark Alert Sheet
- (void)sendAlertWithContext:(NSString *)context {
	NSLog(@"%s", _cmd);
	NSString *titleText;
	NSString *bodyText;

	titleText = [NSString stringWithFormat:@"Clear High Scores!"];
	bodyText = [NSString stringWithFormat:@"You are about to clear your high scores. There is no turning back."];

	UIAlertSheet	*alertSheet = [[UIAlertSheet alloc] initWithFrame:CGRectMake(0,240,320,240)];
	[alertSheet setTitle:titleText];
	[alertSheet setContext:context];
	[alertSheet setBodyText:bodyText];
	[alertSheet addButtonWithTitle:@"Ok"];
	[alertSheet addButtonWithTitle:@"Cancel"];
	[alertSheet setDelegate: self];
	[alertSheet popupAlertAnimated:YES];
}

- (void)alertSheet:(UIAlertSheet *)sheet buttonClicked:(int)button {
	if ([[sheet context] isEqualToString:@"clearhighscores"]) {
		if (button == 1) {
			[defaults clearHighScores];
			[gameMenuView sendClearHighScores];
		}
	}
	[sheet dismissAnimated:YES];
	[sheet release];
}

#pragma mark Application Accessors
- (void)setNavBarLeftButton:(NSString *)left withStyle:(int)lstyle rightButton:(NSString *)right withStyle:(int)rstyle
{
	[navBar showLeftButton:left withStyle:lstyle rightButton:right withStyle:rstyle];
}

- (void)setNavBarTitle:(NSString *)newTitle
{
	[newTitle retain];
	[title release];
	title = newTitle;
	[navBarTitle setTitle:title];
}

- (int)currentState
{
	return currentState;
}

- (void)setCurrentState:(int)newCurrentState
{	
	currentState = newCurrentState;
}

- (int)previousState
{
	return previousState;
}

- (void)setPreviousState:(int)newPreviousState
{
	previousState = newPreviousState;
}



#pragma mark Dealloc
- (void)dealloc
{
	[gameView release];
	[gameMenuView release];
	[navBarTitle release];
	[navBar release];
	[mainView release];
	[mainWindow release];
	[defaults release];
	[super dealloc];
}

@end